package com.rs.push;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.rs.cache.QueueName;
import com.rs.controller.websocket.WebSocketServer;
import com.rs.entity.basic.DeviceStatus;
import com.rs.entity.task.Command;
import com.rs.entity.task.CommandResponse;
import com.rs.entity.task.NodeReport;
import com.rs.processor.VehicleStatusProcessor;
import com.rs.util.ApplicationContextUtil;
import com.rs.util.NodeUtil;
import com.rs.util.VehicleUtil;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 推送消息
 *
 * @author zhouwz
 * @date 2020/9/13 15:59
 */
@Slf4j
@Component
@NoArgsConstructor
public class DevicePushMessage {

    public static Map<String, String> nodeReportHistory = new ConcurrentHashMap<>();

    /**
     * 点位上报
     */
    public static void nodeReport(String vehicleCode, boolean flag) {
        DeviceStatus vehicleStatus = VehicleUtil.getCurrentStatus(vehicleCode);
        String nodeName = NodeUtil.getNodeNameByCode(vehicleStatus.getNodeCode());
        NodeReport nodeReport = new NodeReport()
                .setAngle(vehicleStatus.getAngle())
                .setDeviceNo(vehicleCode)
                .setNodeName(nodeName)
                .setArriveTime(new Date());
        if (flag || nodeReportHistory.get(vehicleCode) == null || !nodeReportHistory.get(vehicleCode).equals(nodeName)) {
            log.info("{} 点位上报中:{}", vehicleCode, nodeReport.toString());
            nodeReportHistory.put(vehicleCode, nodeName);
            sendRabbitMsg(BeanUtil.beanToMap(nodeReport), QueueName.UPLOAD_DEVICE_NODE_QUEUE);
        }
    }

    /**
     * 状态上报
     */
    public static void reportStatus2Rcs(String vehicleCode) {
        DeviceStatus vehicleStatus = VehicleUtil.getCurrentStatus(vehicleCode);
        VehicleStatusProcessor.chargeToAvailableHandler(vehicleStatus);
        log.info("{} 状态上报中:{}", vehicleCode, vehicleStatus.toString());
        Map<String, Object> param = BeanUtil.beanToMap(vehicleStatus);
        param.remove("nodeName");
        param.remove("nodeCode");
        sendRabbitMsg(param, QueueName.UPLOAD_DEVICE_STATUS_QUEUE);
        websocketPushMessage(vehicleStatus);
    }

    /**
     * 推送消息到websocket
     */
    public static void websocketPushMessage(DeviceStatus statusEntity) {
        try {
            WebSocketServer.sendMessage(JSONUtil.toJsonStr(statusEntity));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 命令完成返回值
     */
    public static void reportReceiveCommand2Rcs(Command command) {
        if (command != null) {
            CommandResponse commandResponse = new CommandResponse()
                    .setCommandNo(command.getCommandNo())
                    .setDeviceNo(command.getDeviceNo())
                    .setCommandType(command.getCommandType())
                    .setResult(1)
                    .setFailIndex(-1);
            sendRabbitMsg(BeanUtil.beanToMap(commandResponse), QueueName.RECEIVE_COMMAND_QUEUE);
        }
    }

    private static void sendRabbitMsg(Map<String, Object> param, String queueName) {
        RabbitTemplate rabbitTemplate = ApplicationContextUtil.getBean(RabbitTemplate.class);
        assert rabbitTemplate != null;
        rabbitTemplate.convertAndSend(queueName, param);
    }
}
